import java.io.*;


public class BitOutStream {
	private OutputStream out;
	private int currentByte;//between 00000000 and 11111111
	private int numBitsInCurrentByte;//between 0 and 7
	
	public BitOutStream(OutputStream output){
		if (output == null){
			throw new NullPointerException("output stream is null");
		}
		out = output;
		currentByte = 0;
		numBitsInCurrentByte = 0;
	}
	
	// Writes a bit to the stream. The specified bit must be 0 or 1.
	public void write(int b) throws IOException {
		if (!(b == 0 || b == 1))
			throw new IllegalArgumentException("writes bit must be 0 or 1");
		currentByte = currentByte << 1 | b; //shift the bit left of 1 character and insert b in the void
		numBitsInCurrentByte++;
		if (numBitsInCurrentByte == 8) {
			out.write(currentByte);
			numBitsInCurrentByte = 0;
		}
	}
	
	// Writes a binary string to the stream. 
	public void write(String b) throws IOException {
		for(int i = 0; i < b.length(); i++){
			write(Integer.parseInt(b.substring(i, i+1)));
		}
	}
	
	
	// Closes this stream and the underlying OutputStream. If called when this bit stream is not at a byte boundary, then the minimum number of zeros (between 0 and 7) are written as padding to reach a byte boundary.
	public void close() throws IOException {
		while (numBitsInCurrentByte != 0)
			write(0);
		out.close();
	}
}
